// code 1 thread:creat exit join 
#include <string>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
using namespace std;
void *thread_todo_func(void *arg)
{
    // 可以获取调用执行流的线程id
    // 线程id就是共享区内,库维护的线程结构体的地址,里面保存线程的栈结构,相关属性和局部存储
    pthread_t tid = pthread_self();
    string thread_name(static_cast<char *>(arg));
    // 线程分离, 分离后不再关心子线程的退出情况,并且自动释放资源,但还是要保证先于主线程退出
    // 更推荐于主线程去分离,这样能确保主线程如果join会失败,不会因为执行流调度顺序不确定导致先join再执行到detach
    // pthread_detach(tid);
    int n = 5;
    while (n--)
    {
        cout << thread_name << " 运行中... "
             << " tid: " << (void *)tid << endl;
        sleep(1);
    }
    //通过void*来返回线程退出码,通过以下方式,退出码会通过join里的输出型参数传递
    //线程退出的方式1 return
    // return (void*)999;
    //线程退出的方式2 pthread_exit
    pthread_exit((void *)999);
    //线程的退出方式3,主线程调用 pthread_cancel
    //线程退出方式4,代码执行完毕,自动返回0
}

int main()
{
#define thread_name(n) ("thread_" #n)
    pthread_t tid;

    if (!pthread_create(&tid, nullptr, thread_todo_func, (void *)"thread"))
        cout << "创建线程成功!" << endl;
    int count = 10;
    // pthread_cancel(tid);
    while (count--)
    {
        cout << "主线程运行中..." << endl;
        sleep(1);
    }
    //阻塞等待回收子线程,若不回收会造成类似僵尸子进程的内存泄漏问题
    cout << "主线程调用join" << endl;
    //输出型参数获取返回值
    void *thread_ret = malloc(16);
    int join_ret = pthread_join(tid, (void **)thread_ret);
    if (!join_ret)
        cout << "等待线程成功,返回值: " << *(long long *)thread_ret << endl;
    free(thread_ret);
    return join_ret;
}